package com.nd.fastdp.sys.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nd.fastdp.framework.exception.BusinessException;
import com.nd.fastdp.framework.pojo.constant.VerifyRespCodeEnum;
import com.nd.fastdp.framework.pojo.dto.DelParam;
import com.nd.fastdp.sys.convert.ResourceConvert;
import com.nd.fastdp.sys.convert.ResourceDataScopeConvert;
import com.nd.fastdp.sys.dao.ResourceDataScopeMapper;
import com.nd.fastdp.sys.dao.ResourceMapper;
import com.nd.fastdp.sys.model.bo.resource.ResourceBO;
import com.nd.fastdp.sys.model.bo.resource.ResourceDataScopeBO;
import com.nd.fastdp.sys.model.dto.resource.*;
import com.nd.fastdp.sys.model.entity.Resource;
import com.nd.fastdp.sys.model.entity.ResourceDataScope;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class ResourceServiceImpl implements ResourceService {

    @Autowired
    private ResourceMapper resourceMapper;

    @Autowired
    private ResourceDataScopeMapper resourceDataScopeMapper;

    @Override
    public ResourceBO add(ResourceAddParam param) {

        Resource resource = ResourceConvert.INSTANCE.from(param);

        if(resourceMapper.isExist(resource.getCode())){
            throw new BusinessException(VerifyRespCodeEnum.CODE_EXIST);
        }

        if(StringUtils.isEmpty(resource.getParentCode()))
            resource.setParentCode("");

        resourceMapper.insert(resource);

        //--------------------------------添加数据权限--开始---------------------------------------------
        if(param.getDataScopes() != null){
            for (DataScopeParam dataScopeParam : param.getDataScopes()){

                dataScopeParam.setLoginUser(param.getLoginUser());
                dataScopeParam.setResourceCode(resource.getCode());

                ResourceDataScope dataScope = ResourceDataScopeConvert.INSTANCE.from(dataScopeParam);

                resourceDataScopeMapper.insert(dataScope);
            }
        }
        //--------------------------------添加数据权限--结束---------------------------------------------


        return ResourceConvert.INSTANCE.to(resource);
    }

    @Override
    public void del(DelParam param) {
        resourceMapper.del(param);
    }

    @Override
    @Transactional
    public ResourceBO modify(ResourceModifyParam param) {

        Resource resource = ResourceConvert.INSTANCE.from(param);

        if(resourceMapper.isExist(resource.getId(), resource.getCode())){
            throw new BusinessException(VerifyRespCodeEnum.CODE_EXIST);
        }

        resourceMapper.updateById(resource);

        //--------------------------------添加数据权限--开始---------------------------------------------
        Resource target = resourceMapper.selectById(param.getId());
        resourceDataScopeMapper.delByResourceCode(target.getCode());
        if(param.getDataScopes() != null){
            for (DataScopeParam dataScopeParam : param.getDataScopes()){

                dataScopeParam.setLoginUser(param.getLoginUser());
                dataScopeParam.setResourceCode(target.getCode());

                ResourceDataScope dataScope = ResourceDataScopeConvert.INSTANCE.from(dataScopeParam);

                resourceDataScopeMapper.insert(dataScope);
            }
        }
        //--------------------------------添加数据权限--结束---------------------------------------------

        return get(resource.getId());
    }

    @Override
    public ResourceBO get(String id) {

        Resource resource = resourceMapper.selectById(id);

        ResourceBO resourceBO = ResourceConvert.INSTANCE.to(resource);

        fillDataScope(resourceBO);

        return resourceBO;
    }

    @Override
    public ResourceBO getByCode(String code) {

        Resource resource = resourceMapper.getByCode(code);

        ResourceBO resourceBO = ResourceConvert.INSTANCE.to(resource);

        fillDataScope(resourceBO);

        return resourceBO;
    }

    @Override
    public List<ResourceBO> findByUserId(String userId) {

        List<Resource> resources =  resourceMapper.findByUserId(userId);

        List<ResourceBO> resourceBOS = ResourceConvert.INSTANCE.to(resources);

        return resourceBOS;
    }

    @Override
    public List<ResourceBO> listAllEnable() {

        List<Resource> resources =  resourceMapper.listAllEnable();

        List<ResourceBO> resourceBOS = ResourceConvert.INSTANCE.to(resources);

        return resourceBOS;
    }

    @Override
    public List<ResourceBO> listAll() {

        List<Resource> resources =  resourceMapper.listAll();

        List<ResourceBO> resourceBOS = ResourceConvert.INSTANCE.to(resources);

        return resourceBOS;
    }

    @Override
    public List<ResourceBO> list(ResourceListParam param) {

        List<Resource> resources =  resourceMapper.list(param);

        List<ResourceBO> resourceBOS = ResourceConvert.INSTANCE.to(resources);

        return resourceBOS;
    }

    @Override
    public Page<ResourceBO> page(ResourceQueryParam param) {

        IPage<Resource> page =  resourceMapper.page(param.getPage(), param);

        return ResourceConvert.INSTANCE.to(page);
    }

    @Override
    public List<ResourceDataScopeBO> findDataScopeByUserId(String userId) {
        List<ResourceDataScope> dataScopeBOS= resourceDataScopeMapper.findByUserId(userId);
        return ResourceConvert.INSTANCE.toDataScope(dataScopeBOS);
    }

    @Override
    public List<ResourceDataScopeBO> listAllDataScope() {
        List<ResourceDataScope> dataScopeBOS= resourceDataScopeMapper.listAll();
        return ResourceConvert.INSTANCE.toDataScope(dataScopeBOS);
    }

    private void fillDataScope(ResourceBO resourceBO){

        if(resourceBO == null){
            return;
        }

        List<ResourceDataScope> dataScopes = resourceDataScopeMapper.listByResourceCode(resourceBO.getCode());
        List<ResourceDataScopeBO> dataScopeBOs = ResourceDataScopeConvert.INSTANCE.to(dataScopes);
        resourceBO.setDataScopes(dataScopeBOs);
    }

    private void fillDataScope(List<ResourceBO> resourceBOs){

        for(ResourceBO resourceBO : resourceBOs){
            fillDataScope(resourceBO);
        }
    }
}
